﻿#ifndef PLCSERVERBASE_H
#define PLCSERVERBASE_H

#include <QObject>
#include <QModbusServer>
#include "ComCommon.h"

enum PLCServerType{
    PST_ModbusTcp = 0,
    PST_ModbusRtu
};


struct PLCServerConfig{
    QString name;//通讯名
    PLCServerType type;//类型
    int serverID;//站号
    quint16 addrCount;
    TcpComConfig tcp;//tcp配置，modbustcp使用
    SerialComConfig serial;//serail配置，modbusrtu使用
    PLCServerConfig() : name("Server"), type(PST_ModbusTcp), serverID(0), addrCount(100), tcp(TcpComConfig()), serial(SerialComConfig()){
    }

    PLCServerConfig(QString name, PLCServerType type, int serverID, quint16 addrCount){
        this->name = name;
        this->type = type;
        this->serverID = serverID;
        this->addrCount = addrCount;
    }
    ~PLCServerConfig()
    {
    }
    friend QDataStream &operator<<(QDataStream &out, const PLCServerConfig &config)
    {
        out << config.name
            << config.type
            << config.serverID
            << config.tcp
            << config.serial
            << config.addrCount;
        return out;
    }
    friend QDataStream &operator>>(QDataStream &in, PLCServerConfig &config)
    {
        in >> config.name
            >> config.type
            >> config.serverID
            >> config.tcp
            >> config.serial
            >> config.addrCount;
        return in;
    }
};
Q_DECLARE_METATYPE(PLCServerConfig)

class PLCServerBase : public QObject
{
    Q_OBJECT
public:
    explicit PLCServerBase(QObject *parent = nullptr);
    virtual ~PLCServerBase(){}

    static QMap<ComState, QString> mapPLCServerStateText;
    static QMap<PLCServerType, QString> mapPLCServerTypeText;

    void setConfig(const PLCServerConfig &plcConfig){mConfig = plcConfig;}
    ComState getPLCState() const {return mPLCState;}

signals:
    void sigStateChanged(const ComState& state);
    void sigErrOccur(const QString& msg);
    void sigData(const PLCRequestData& requestData);
    void sigMsg(const QString& msg);
public slots:
    virtual void onInit();
    virtual void onQuit();
    virtual void onWrite(const PLCRequestData& requestData);
    virtual void onRead(const PLCRequestData& requestData);
    void onPLCConfigChanged(const PLCServerConfig &plcConfig);
protected:
    virtual void setupDeviceData();
    virtual void processData(const PLCRequestData& requestData){};
    virtual void onClientConnect(QString addr){}
protected slots:
    void setServerState(ComState state);
    //    void readData(QModbusDataUnit::RegisterType table, const QList<ModbusValue>& lstValue);
    void readData(QModbusDataUnit::RegisterType table, int address, int size);
    void writeData(const QModbusDataUnit& newData);
    virtual void initCom() = 0;
public:
    PLCServerConfig mConfig;
protected:
    ComState mPLCState = CS_Invalid;
    QModbusServer* mServer = nullptr;
    QModbusDataUnit coilDataPre;
    QModbusDataUnit holdDataPre;
    QModbusDataUnit discreDataPre;
    QModbusDataUnit inputDataPre;
};
#endif // PLCSERVERBASE_H
